
//#include "head.h"
//#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#include <iostream>

#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/RedisMessage.h>
using std::cout;
using std::endl;
using std::string;
using std::vector;

static WFFacilities::WaitGroup waitGroup(1);

//全局变量尽量少使用，甚至不用
//设计为全局变量，希望其可以跨模块调用
//int gnumber = 1;

void sighandler(int num)
{
    printf(">> sig num %d is comming\n", num);
    //调用一次done方法，计数器的值减1
    waitGroup.done();
}

void seriesCallback(const SeriesWork * series)
{
    printf("seriesCallback is running\n");
    int * context = (int *)series->get_context();
    cout << "seriesCallback printing: context is " << *context << endl;

    delete context;
}

//4. 设计回调函数
void redisCallback(WFRedisTask * redistask)
{
    //获取序列的context, 访问资源
    /* auto series = series_of(redistask); */
    /* int * pnumber = static_cast<int*>(series->get_context()); */
    /* printf("*pnumber: %d, pnumber: %p\n", *pnumber, pnumber); */
    printf("redisCallback is running\n");

    // 1. 错误的检测
    int state = redistask->get_state();
    int error = redistask->get_error();
    switch(state) {
    case WFT_STATE_SYS_ERROR:
        printf("system error: %s\n", strerror(error)); break;
    case WFT_STATE_DNS_ERROR:
        printf("dns error: %s\n", gai_strerror(error)); break;
    case WFT_STATE_SUCCESS:
        break;
    }
    if(state != WFT_STATE_SUCCESS) {
        printf("error occurs!\n");
        return;
    }
    printf("\n\ntask is ok!\n");
    //2. 对Redis请求报文进行遍历
    auto req = redistask->get_req();
    string command;
    vector<string> params;
    req->get_command(command);
    req->get_params(params);
    cout << "> RedisRequest: " << command << " ";
    for(auto & elem : params) {
        cout << elem << " ";
    }
    cout << endl << endl;

    //3. 对Redis响应报文进行遍历
    auto resp = redistask->get_resp();
    protocol::RedisValue result;
    resp->get_result(result);

    if(command == "SET" && result.is_string()){
        cout << "RedisValue is string" << endl;
        cout << result.string_value() << endl;
        //创建第二个任务
        string url = "redis://localhost:6379";
        auto redisTask2 = WFTaskFactory::create_redis_task(
                            url, 1, redisCallback);
        command = "GET";
        params = {"x"};
        redisTask2->get_req()->set_request(command, params);
        //获取序列，并添加第二个的任务, 该操作是在任务线程中进行的
        series_of(redistask)->push_back(redisTask2);
        //初始化序列的回调函数
        series_of(redistask)->set_callback(seriesCallback);

        //在第一个任务执行的末尾，设置共享数据
        int * pnumber = new int(1);
        printf("*pnumber: %d, pnumber: %p\n", *pnumber, pnumber);
        series_of(redistask)->set_context(pnumber);
    } else if (command == "GET") {
        cout << result.string_value() << endl;
        //在第二个任务中,访问序列context中的数据
        int * pnumber = (int*)series_of(redistask)->get_context();
        *pnumber = 10;
        printf("*pnumber: %d, pnumber: %p\n", *pnumber, pnumber);
    } else if(result.is_int()) {
        cout << "RedisValue is integer" << endl;
        cout << result.int_value() << endl;
    } else if(result.is_array()) {
        cout << "RedisValue is array" << endl;
        for(size_t i = 0; i < result.arr_size(); ++i) {
            cout << i+1 << ") " 
                 << result.arr_at(i).string_value() 
                 << endl;
        }
    }
}

void test0()
{
    signal(SIGINT, sighandler);
    string url = "redis://localhost:6379";
    auto redisTask = WFTaskFactory::create_redis_task(url, 1, redisCallback);

    string command = "SET";
    vector<string> params {"x", "123"};
    redisTask->get_req()->set_request(command, params);
    //当调用了start方法之后，就创建了一个序列
    //在另外一个线程A在执行redisTask
    redisTask->start();

    //当调用wait方法会阻塞当前线程
    waitGroup.wait();

    cout << "test0 exit" << endl;
}


int main()
{
    test0();
    return 0;
}

